<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Data Stream</title>
		<meta name="viewport" content="width=device-width, initial-scale=1">

		<link rel="stylesheet" href="../dist/uPlot.min.css">
	</head>
	<body>
		<script src="../dist/uPlot.iife.js"></script>
		<h2 id="wait">Loading lib....</h2>

		<script>
			function round2(val) {
				return Math.round(val * 100) / 100;
			}

			function round3(val) {
				return Math.round(val * 1000) / 1000;
			}

			function prepData(packed) {
				console.time('prep');

				// epoch,idl,recv,send,read,writ,used,free

				const numFields = packed[0];

				packed = packed.slice(numFields + 1);

				// 55,550 data points x 3 series = 166,650
				let data = [
					Array(packed.length/numFields),
					Array(packed.length/numFields),
					Array(packed.length/numFields),
					Array(packed.length/numFields),
				];

				for (let i = 0, j = 0; i < packed.length; i += numFields, j++) {
					data[0][j] = packed[i] * 60;
					data[1][j] = round3(100 - packed[i+1]);
					data[2][j] = round2(100 * packed[i+5] / (packed[i+5] + packed[i+6]));
					data[3][j] = packed[i+3];
				}

				console.timeEnd('prep');

				return data;
			}

			function makeChart(data) {
				console.time('chart');

				function sliceData(start, end) {
					let d = [];

					for (let i = 0; i < data.length; i++)
						d.push(data[i].slice(start, end));

					return d;
				}

				let interval = 100;

				let makeFmt = suffix => (u, v, sidx, didx) => {
					if (didx == null) {
						let d = u.data[sidx];
						v = d[d.length - 1];
					}

					return v == null ? null : v.toFixed(1) + suffix;
				};

				const opts = {
					title: "Fixed length / sliding data slices",
					width: 1600,
					height: 600,
					cursor: {
						drag: {
							setScale: false,
						}
					},
					select: {
						show: false,
					},
					series: [
						{
							value: (u, v, sidx, didx) => {
								if (didx == null) {
									let d = u.data[sidx];
									v = d[d.length - 1];
								}

								return v;
							}
						},
						{
							label: "CPU",
							scale: "%",
							value: makeFmt('%'),
							stroke: "red",
						},
						{
							label: "RAM",
							scale: "%",
							value: makeFmt('%'),
							stroke: "blue",
						},
						{
							label: "TCP Out",
							scale: "mb",
							value: makeFmt('MB'),
							stroke: "green",
						}
					],
					axes: [
						{},
						{
							scale: '%',
							values: (u, vals, space) => vals.map(v => +v.toFixed(1) + "%"),
						},
						{
							side: 1,
							scale: 'mb',
							values: (u, vals, space) => vals.map(v => +v.toFixed(2) + " MB"),
							grid: {show: false},
						},
					]
				};

				let start1 = 0;
				let len1 = 3000;

				let data1 = sliceData(start1, start1 + len1);
				let uplot1 = new uPlot(opts, data1, document.body);

				setInterval(function() {
					start1 += 10;
					let data1 = sliceData(start1, start1 + len1);
					uplot1.setData(data1);
				}, interval);


				const opts2 = {
					title: "Increasing length data",
					width: 1600,
					height: 600,
					cursor: {
						drag: {
							setScale: false,
						}
					},
					select: {
						show: false,
					},
					series: [
						{},
						{
							label: "CPU",
							scale: "%",
							value: (u, v) => v == null ? null : v.toFixed(1) + "%",
							stroke: "red",
						},
						{
							label: "RAM",
							scale: "%",
							value: (u, v) => v == null ? null : v.toFixed(1) + "%",
							stroke: "blue",
						},
						{
							label: "TCP Out",
							scale: "mb",
							value: (u, v) => v == null ? null : v.toFixed(2) + " MB",
							stroke: "green",
						}
					],
					axes: [
						{},
						{
							scale: '%',
							values: (u, vals, space) => vals.map(v => +v.toFixed(1) + "%"),
						},
						{
							side: 1,
							scale: 'mb',
							values: (u, vals, space) => vals.map(v => +v.toFixed(2) + " MB"),
							grid: {show: false},
						},
					],
				};

				let start2 = 0;
				let len2 = 3000;

				let data2 = sliceData(start2, start2 + len2);
				let uplot2 = new uPlot(opts2, data2, document.body);

				setInterval(function() {
					len2 += 10;
					let data2 = sliceData(start2, start2 + len2);
					uplot2.setData(data2);
				}, interval);


				const opts3 = {
					title: "Increasing length data, static x scale",
					width: 1600,
					height: 600,
					cursor: {
						drag: {
							setScale: false,
						}
					},
					select: {
						show: false,
					},
					scales: {
						'x': {
							auto: false,
							range: (min, max) => [1566453600, 1566813540],
						},
						'%': {
							auto: false,
							range: (min, max) => [0, 100],
						},
						'mb': {
							auto: false,
							range: (min, max) => [0, 70],
						},
					},
					series: [
						{},
						{
							label: "CPU",
							scale: "%",
							value: (u, v) => v == null ? null : v.toFixed(1) + "%",
							stroke: "red",
						},
						{
							label: "RAM",
							scale: "%",
							value: (u, v) => v == null ? null : v.toFixed(1) + "%",
							stroke: "blue",
						},
						{
							label: "TCP Out",
							scale: "mb",
							value: (u, v) => v == null ? null : v.toFixed(2) + " MB",
							stroke: "green",
						}
					],
					axes: [
						{},
						{
							scale: '%',
							values: (u, vals, space) => vals.map(v => +v.toFixed(1) + "%"),
						},
						{
							side: 1,
							scale: 'mb',
							values: (u, vals, space) => vals.map(v => +v.toFixed(2) + " MB"),
							grid: {show: false},
						},
					],
				};

				let start3 = 0;
				let len3 = 10;

				let data3 = sliceData(start3, start3 + len3);
				let uplot3 = new uPlot(opts3, data3, document.body);

				setInterval(function() {
					len3 += 10;
					let data3 = sliceData(start3, start3 + len3);
					uplot3.setData(data3);
				}, interval);

				wait.textContent = "Done!";
				console.timeEnd('chart');
			}

			let wait = document.getElementById("wait");
			wait.textContent = "Fetching data.json (2.07MB)....";
			fetch("../bench/data.json").then(r => r.json()).then(packed => {
				wait.textContent = "Rendering...";
				let data = prepData(packed);
				setTimeout(() => makeChart(data), 0);
			});
		</script>
	</body>
</html>